import logging
from dataclasses import dataclass, field
from enum import Enum, auto
from typing import Dict, Callable, List, Any

from PySide6.QtCore import QObject, Signal


class 事件类型(Enum):
    """定义所有可能的事件类型"""
    节点创建 = auto()
    节点删除 = auto()
    节点移动 = auto()
    节点连接 = auto()
    节点断开 = auto()
    布局更新 = auto()
    选择变更 = auto()
    文件打开 = auto()
    文件保存 = auto()
    撤销操作 = auto()
    重做操作 = auto()
    异常发生 = auto()
    性能警告 = auto()

@dataclass
class 事件数据:
    """事件数据基类"""
    类型: 事件类型
    源对象: Any = None
    数据: Dict = field(default_factory=dict)
    时间戳: float = field(default_factory=lambda: time.time())

class 事件管理器(QObject):
    """统一的事件管理器"""
    
    事件发生 = Signal(事件数据)  # 通用事件信号
    
    def __init__(self):
        super().__init__()
        self.logger = logging.getLogger("事件管理器")
        self._处理器: Dict[事件类型, List[Callable]] = {}
        self._初始化事件处理器()
        
    def _初始化事件处理器(self):
        """初始化默认的事件处理器"""
        for 事件 in 事件类型:
            self._处理器[事件] = []
            
    def 注册处理器(self, 事件: 事件类型, 处理函数: Callable):
        """注册事件处理器
        
        Args:
            事件: 要处理的事件类型
            处理函数: 处理事件的函数
        """
        if 事件 not in self._处理器:
            self._处理器[事件] = []
        self._处理器[事件].append(处理函数)
        self.logger.debug(f"注册事件处理器: {事件.name} -> {处理函数.__name__}")
        
    def 移除处理器(self, 事件: 事件类型, 处理函数: Callable):
        """移除事件处理器"""
        if 事件 in self._处理器 and 处理函数 in self._处理器[事件]:
            self._处理器[事件].remove(处理函数)
            self.logger.debug(f"移除事件处理器: {事件.name} -> {处理函数.__name__}")
            
    def 触发事件(self, 事件数据: 事件数据):
        """触发事件
        
        Args:
            事件数据: 事件相关的数据
        """
        try:
            # 记录事件
            self.logger.info(f"触发事件: {事件数据.类型.name}")
            self.logger.debug(f"事件数据: {事件数据.数据}")
            
            # 发送Qt信号
            self.事件发生.emit(事件数据)
            
            # 调用所有注册的处理器
            if 事件数据.类型 in self._处理器:
                for 处理函数 in self._处理器[事件数据.类型]:
                    try:
                        处理函数(事件数据)
                    except Exception as e:
                        self.logger.error(f"事件处理器异常: {处理函数.__name__} -> {str(e)}")
                        
        except Exception as e:
            self.logger.error(f"事件触发失败: {str(e)}")
            
    def 清除所有处理器(self):
        """清除所有注册的事件处理器"""
        self._处理器.clear()
        self._初始化事件处理器()
        self.logger.info("清除所有事件处理器")

# 创建全局事件管理器实例
事件管理器实例 = 事件管理器()

# 特定事件数据类
@dataclass
class 节点事件数据(事件数据):
    """节点相关的事件数据"""
    节点ID: str = None
    位置: tuple = None
    大小: tuple = None

@dataclass
class 连接事件数据(事件数据):
    """连接相关的事件数据"""
    起始节点ID: str = None
    结束节点ID: str = None
    连接类型: str = None

@dataclass
class 文件事件数据(事件数据):
    """文件操作相关的事件数据"""
    文件路径: str = None
    操作结果: bool = None
    错误信息: str = None

@dataclass
class 异常事件数据(事件数据):
    """异常相关的事件数据"""
    异常类型: str = None
    异常信息: str = None
    堆栈信息: str = None

# 装饰器：用于自动记录事件
def 记录事件(事件类型: 事件类型):
    def 装饰器(func):
        def 包装(*args, **kwargs):
            try:
                结果 = func(*args, **kwargs)
                事件数据 = 事件数据(
                    类型=事件类型,
                    源对象=args[0] if args else None,
                    数据={"结果": 结果} if 结果 is not None else {}
                )
                事件管理器实例.触发事件(事件数据)
                return 结果
            except Exception as e:
                异常数据 = 异常事件数据(
                    类型=事件类型.异常发生,
                    源对象=args[0] if args else None,
                    异常类型=type(e).__name__,
                    异常信息=str(e),
                    堆栈信息=traceback.format_exc()
                )
                事件管理器实例.触发事件(异常数据)
                raise
        return 包装
    return 装饰器 